import 'dart:ffi';
import 'dart:io';

import 'package:path/path.dart';
import 'package:simulator/utils/log.dart';
import 'package:win32/win32.dart';

class Utils {
  static final Utils _instance = Utils._internal();
  Utils._internal();

  static Utils getInstance() => _instance;

  late final String execDir;
  final List<Function> shutdown = List.empty(growable: true);

  void init() {
    execDir = dirname(Platform.resolvedExecutable);
    print(execDir);
  }

  void addShutdownHook(Function function) => shutdown.add(function);

  void exitHook() {
    for (var element in shutdown.reversed) {
      element.call();
    }
  }

  void setupSignal() {
    final lpEnumFunc =
        NativeCallable<PHANDLER_ROUTINE>.isolateLocal(f, exceptionalReturn: 0);

    SetConsoleCtrlHandler(lpEnumFunc.nativeFunction, 1);
  }

  Future<void> abort(String err) {
    LogPrint.logErr(err);
    Utils.getInstance().exitHook();
    exit(255);
  }
}

int f(int dwCtrlType) {
  print('SetConsoleCtrlHandler');
  Utils.getInstance().exitHook();
  return 0;
}

extension SignedData on int {
  ///判断一个数是否溢出有符号数表示范围
  bool overSize({int width = 8}) {
    return this > 127 || this < -128;
  }

  ///进行有符号数加法计算
  int signedAdd(int other, {int width = 8}) {
    return toSigned(width) + other.toSigned(width);
  }

  ///进行有符号数减法计算
  int signedSub(int other, {int width = 8}) {
    return toSigned(width) - other.toSigned(width);
  }

  bool getBool() {
    return this == 0 ? false : true;
  }

  int mask(int mask) => this & mask;
}

extension SignedBool on bool {
  int toInt() {
    return this ? 1 : 0;
  }
}
